package com.weixin.paleituo.activity;

import android.annotation.SuppressLint;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Handler;
import android.os.Message;
import android.support.v4.content.ContextCompat;
import android.text.Editable;
import android.text.TextUtils;
import android.view.View;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;

import com.alipay.sdk.app.PayTask;
import com.tencent.mm.opensdk.modelpay.PayReq;
import com.tencent.mm.opensdk.openapi.IWXAPI;
import com.tencent.mm.opensdk.openapi.WXAPIFactory;
import com.weixin.paleituo.R;
import com.weixin.paleituo.annotation.PayType;
import com.weixin.paleituo.annotation.SuccessFromType;
import com.weixin.paleituo.annotation.WeChatPayType;
import com.weixin.paleituo.application.BaseApplication;
import com.weixin.paleituo.base.BasePersonActivity;
import com.weixin.paleituo.bean.CouponsBean;
import com.weixin.paleituo.bean.OrderCreatedBean;
import com.weixin.paleituo.bean.StatusCode;
import com.weixin.paleituo.bean.WeiChatPayBean;
import com.weixin.paleituo.contans.Contans;
import com.weixin.paleituo.factory.ThreadFactory;
import com.weixin.paleituo.http.HttpUtil;
import com.weixin.paleituo.http.ProgressSubscriber;
import com.weixin.paleituo.http.RxHelper;
import com.weixin.paleituo.rxjava.ApiUtils;
import com.weixin.paleituo.util.LoadingDialogUtils;
import com.weixin.paleituo.util.LogUtils;
import com.weixin.paleituo.util.PayResult;
import com.weixin.paleituo.util.StringUtils;
import com.weixin.paleituo.util.ToastUtils;
import com.weixin.paleituo.util.UIUtils;
import com.weixin.paleituo.view.LoadingPagerHead;
import com.weixin.paleituo.view.TipsDialog;
import com.weixin.paleituo.wxapi.WXPayEntry;

import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import butterknife.BindView;
import butterknife.OnClick;
import butterknife.OnTextChanged;
import io.reactivex.Observable;
import io.reactivex.Observer;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.functions.Consumer;
import io.reactivex.functions.Function;
import io.reactivex.schedulers.Schedulers;

/**
 * 舒社收银台
 * 普通订单只能选择方式进行支付，
 * 定制订单可再次界面选择优惠券，优惠券逻辑与创建订单界面逻辑相同
 *
 * @author fengzhen
 * @version v1.0, 2018/4/6
 */
public class CheckstandActivity extends BasePersonActivity {

    public static final int REQUEST_ORDER_COUPONS = 0x122;

    private static final int SDK_PAY_FLAG = 1;

    public static final String INTENT_ORDER_INFO = "intent_order_info";
    public static final String INTENT_ORDER_TYPE = "intent_order_type";
    public static final String INTENT_ORDER_TIME = "intent_order_time";

    @BindView(R.id.tv_wechant_activity_checkstand)
    TextView mTvWechantActivityCheckstand;
    @BindView(R.id.tv_zhifubao_activity_checkstand)
    TextView mTvZhifubaoActivityCheckstand;
    @BindView(R.id.tv_coupons)
    TextView mTvCoupons;
    @BindView(R.id.tv_tag_coupons_activity_checkstand)
    TextView mTvTagCouponsActivityCheckstand;
    @BindView(R.id.tv_deduction_coupon_activity_checkstand)
    TextView mTvDeductionCouponActivityCheckstand;
    @BindView(R.id.tv_sum_activity_checkstand)
    TextView mTvSumActivityCheckstand;
    @BindView(R.id.relative_sum_activity_checkstand)
    RelativeLayout mRelativeSumActivityCheckstand;
    @BindView(R.id.tv_pay_express_activity_checkstand)
    TextView mTvPayExpressActivityCheckstand;
    @BindView(R.id.relative_pay_express_activity_checkstand)
    RelativeLayout mRelativePayExpressActivityCheckstand;
    @BindView(R.id.tv_coupon_activity_checkstand)
    TextView mTvCouponActivityCheckstand;
    @BindView(R.id.linear_coupons_activity_checkstand)
    LinearLayout mLinearCouponsActivityCheckstand;
    @BindView(R.id.btn_pay_activity_checkstand)
    Button mBtnPayActivityCheckstand;

    private LoadingPagerHead mLoadingPagerHead;

    private DecimalFormat format = new DecimalFormat("#0.00");

    // 订单类型 定制/普通 0/1
    private int mOrderType = 1;
    private OrderCreatedBean mOrderInfo;
    // 支付类型 微信/支付宝 1/2
    private int mPayType = PayType.WEICHANT;
    // 商品实际支付总价  默认=订单价格
    private double mGoodsSumCurrent;
    // 是否有优惠券  默认没有
    private boolean hasCoupons = false;
    private ArrayList<CouponsBean> mChooseCoupons;
    private ArrayList<CouponsBean> mAllCoupons = new ArrayList<>();
    // 优惠券优惠金额
    private double mCouponsSum = 0.00;
    // 运费
    private double mExpressSum = 0.00;

    private Dialog loadingDialog;
    private TipsDialog mExitDialog;

    private IWXAPI mIWXAPI;

    private Disposable mTimerDisposable;
    private long mTimeStamp = -1;
    private String mTextLeaveTips = "";

    /**
     * 跳转收银台
     *
     * @param type      订单类型   定制/普通  0/1
     * @param orderData 订单信息
     * @return
     */
    public static Intent call2CheckstandActivity(Context context, int type, OrderCreatedBean orderData) {
        Intent intent = new Intent(context, CheckstandActivity.class);
        intent.putExtra(INTENT_ORDER_INFO, orderData);
        intent.putExtra(INTENT_ORDER_TYPE, type);
        return intent;
    }

    @Override
    protected View getContentView(Context context) {
        mLoadingPagerHead = new LoadingPagerHead(this) {
            @Override
            protected void close() {
                onBackPressed();
            }

            @Override
            protected View createSuccessView() {
                return UIUtils.inflate(CheckstandActivity.this, R.layout.activity_checkstand);
            }

            @Override
            protected void reLoading() {
                getCouponsList();
            }
        };
        return mLoadingPagerHead;
    }

    @Override
    protected void initView() {
        super.initView();
        Intent intent = getIntent();
        mOrderType = intent.getIntExtra(INTENT_ORDER_TYPE, 1);
        mOrderInfo = (OrderCreatedBean) intent.getSerializableExtra(INTENT_ORDER_INFO);
        mTimeStamp = intent.getLongExtra(INTENT_ORDER_TIME, -1);
        mGoodsSumCurrent = mOrderInfo.getActualPrice();
    }

    @Override
    protected void initData() {
        super.initData();
        mTvTitle.setText("舒社收银台");
        mIWXAPI = WXAPIFactory.createWXAPI(this, WXPayEntry.APP_ID, true);
        mBtnPayActivityCheckstand.setText(String.format(getString(R.string.string_wechat_pay), format.format(mGoodsSumCurrent)));
        mTvWechantActivityCheckstand.setEnabled(true);

        startCountDown();
        getCouponsList();
    }

    @Override
    protected void onDestroy() {
        if (mTimerDisposable != null && !mTimerDisposable.isDisposed()) {
            mTimerDisposable.dispose();
        }
        super.onDestroy();
    }

    /**
     * 订单有效期计时器
     */
    private void startCountDown() {
        final SimpleDateFormat dateFormat = new SimpleDateFormat("HH-mm");
        if (mTimeStamp <= 0) {
            return;
        } else {
            Observable.interval(0, 1, TimeUnit.SECONDS)
                    .subscribeOn(Schedulers.newThread())
                    .observeOn(AndroidSchedulers.mainThread())
                    .map(new Function<Long, Long>() {
                        @Override
                        public Long apply(Long aLong) throws Exception {
                            return mTimeStamp - (aLong * 1000);
                        }
                    })
                    .take(mTimeStamp)
                    .subscribe(new Observer<Long>() {
                        @Override
                        public void onSubscribe(Disposable d) {
                            mTimerDisposable = d;
                        }

                        @Override
                        public void onNext(Long value) {
                            String format = dateFormat.format(new Date(value));
                            String[] split = format.split("-");
                            mTextLeaveTips = String.format(getString(R.string.string_leave_checkstand), split[0], split[1]);

                        }

                        @Override
                        public void onError(Throwable e) {
                        }

                        @Override
                        public void onComplete() {
                            ToastUtils.makeText("订单超时，已失效");
                            MyOrderActivity.startActivity(CheckstandActivity.this, BaseApplication.getUserId(), 4);
                        }
                    });
        }
    }

    @Override
    public void onBackPressed() {
        if (mExitDialog == null) {
            mExitDialog = new TipsDialog.Builder(this)
                    .setContentView("您的订单在24小时内未支付将被取消，请尽快完成支付。")
                    .setTitle("确定要离开收银台？")
                    .setCancelClickListener(new DialogInterface.OnCancelListener() {
                        @Override
                        public void onCancel(DialogInterface dialog) {
                            mExitDialog.dismiss();
                        }
                    })
                    .setLeftButton("继续支付", new View.OnClickListener() {
                        @Override
                        public void onClick(View v) {
                            mExitDialog.dismiss();
                        }
                    })
                    .setRightButton("确定离开", new View.OnClickListener() {
                        @Override
                        public void onClick(View v) {
                            mExitDialog.dismiss();
                            MyOrderActivity.startActivity(CheckstandActivity.this, BaseApplication.getUserId(), 1);
                            finish();
                        }
                    })
                    .build();
        }
        mExitDialog.show();
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.iv_back_activity_basepersoninfo:
                    onBackPressed();
                break;
            case R.id.tv_small_title_layout_head:
                save(v);
                break;
        }
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (resultCode == RESULT_OK) {
            switch (requestCode) {
                case REQUEST_ORDER_COUPONS:
                    mChooseCoupons = (ArrayList<CouponsBean>) data.getSerializableExtra(Contans.INTENT_DATA);
                    double coupon = data.getDoubleExtra(Contans.INTENT_EXTRA, 0.0);
                    mCouponsSum = mOrderInfo.getCouponMoney() > coupon ? coupon : mOrderInfo.getCouponMoney();
                    refreshCoupons();
                    break;
            }
        }
    }

    /**
     * 刷新优惠券信息
     */
    private void refreshCoupons() {
        mTvSumActivityCheckstand.setText(String.format(getString(R.string.string_pay), format.format(mOrderInfo.getActualPrice())));
        mTvPayExpressActivityCheckstand.setText(String.format(getString(R.string.string_sub_pay), format.format(mExpressSum)));
        mTvDeductionCouponActivityCheckstand.setText(String.format(getString(R.string.string_sub_pay), format.format(mCouponsSum)));
        mTvCouponActivityCheckstand.setText(String.format(getString(R.string.string_sub_pay), format.format(mCouponsSum)));
        if (hasCoupons) {
            if (mChooseCoupons == null || mChooseCoupons.size() <= 0) {
                mTvDeductionCouponActivityCheckstand.setText("未选择");
                mTvTagCouponsActivityCheckstand.setVisibility(View.GONE);
            } else {
                mTvCouponActivityCheckstand.setText(String.format(getString(R.string.string_sub_pay), format.format(mCouponsSum)));
                mTvTagCouponsActivityCheckstand.setText(String.format(getString(R.string.string_count_coupons), mChooseCoupons.size()));
                mTvTagCouponsActivityCheckstand.setVisibility(View.VISIBLE);
            }
            mTvDeductionCouponActivityCheckstand.setCompoundDrawablesWithIntrinsicBounds(null, null, ContextCompat.getDrawable(this, R.mipmap.ck), null);
        } else {
            mTvDeductionCouponActivityCheckstand.setText("无可用");
            mTvTagCouponsActivityCheckstand.setVisibility(View.GONE);
            mTvDeductionCouponActivityCheckstand.setCompoundDrawablesWithIntrinsicBounds(null, null, null, null);
        }
    }

    /**
     * 刷新支付按钮文案
     */
    private void refreshPayButton() {
        if (mPayType == PayType.ZHIFUBAO) {
            mBtnPayActivityCheckstand.setText(String.format(getString(R.string.string_zhifubao_pay), format.format(mGoodsSumCurrent)));
        } else {
            mBtnPayActivityCheckstand.setText(String.format(getString(R.string.string_wechat_pay), format.format(mGoodsSumCurrent)));
        }
    }

    /**
     * 获取优惠券数据
     */
    private void getCouponsList() {
        if (mOrderType == 1) {
            // 普通清单不需要
            mLoadingPagerHead.showPagerView(Contans.STATE_SUCCEED);
            mLinearCouponsActivityCheckstand.setVisibility(View.GONE);
        } else {
            mLinearCouponsActivityCheckstand.setVisibility(View.VISIBLE);
            mTvTagCouponsActivityCheckstand.setVisibility(View.GONE);
            Observable<StatusCode<List<CouponsBean>>> couponsForOrder = ApiUtils.getApi().getCouponsForOrder(
                    BaseApplication.getToken(), BaseApplication.getUserId(), String.valueOf(mOrderInfo.getOrderId()), String.valueOf(((int) mOrderInfo.getCouponMoney())));
            HttpUtil.getInstance().toSubscribe(couponsForOrder,
                    new ProgressSubscriber<List<CouponsBean>>(this) {
                        @Override
                        protected void _onNext(StatusCode<List<CouponsBean>> statusCode) {
                            mLoadingPagerHead.showPagerView(Contans.STATE_SUCCEED);
                            mAllCoupons.addAll(statusCode.getData());
                            hasCoupons = statusCode.getData() != null && statusCode.getData().size() > 0;
                            refreshCoupons();
                        }

                        @Override
                        protected void _onError(String message) {
                            mLoadingPagerHead.showPagerView(Contans.STATE_ERROR);
                        }
                    }, "", lifecycleSubject, false, true);
        }
    }

    private void payByWechat(StringBuffer buffer) {
        final Observable<StatusCode<WeiChatPayBean>> weChatPayOrder =
                ApiUtils.getApi().payGoodsOrderByWechat(BaseApplication.getToken(), BaseApplication.getUserId(), mOrderInfo.getOrderId(), buffer.toString())
                        .compose(RxHelper.getObservaleTransformer())
                        .doOnSubscribe(new Consumer<Disposable>() {
                            @Override
                            public void accept(Disposable disposable) throws Exception {
                                if (loadingDialog == null) {
                                    loadingDialog = LoadingDialogUtils.createLoadingDialog(CheckstandActivity.this, "");
                                }
                                LoadingDialogUtils.show(loadingDialog);
                            }
                        })
                        .subscribeOn(AndroidSchedulers.mainThread());
        HttpUtil.getInstance().toSubscribe(weChatPayOrder, new ProgressSubscriber<WeiChatPayBean>(this) {
            @Override
            protected void _onNext(StatusCode<WeiChatPayBean> weiChatPayBeanStatusCode) {
                LoadingDialogUtils.closeDialog(loadingDialog);
                WeiChatPayBean weiChatPayBean = weiChatPayBeanStatusCode.getData();
                if (weiChatPayBeanStatusCode.isFlag() && weiChatPayBean != null) {
                    PayReq req = new PayReq();
                    req.appId = weiChatPayBean.getAppid();
                    req.partnerId = weiChatPayBean.getPartnerid();
                    req.prepayId = weiChatPayBean.getPrepayid();
                    req.nonceStr = weiChatPayBean.getNoncestr();
                    req.timeStamp = weiChatPayBean.getTimestamp();
                    req.packageValue = weiChatPayBean.getPackageX();
                    req.sign = weiChatPayBean.getSign();
                    req.extData = WeChatPayType.FORM_GOODS + "--" + "";

                    if (req.checkArgs()) {
                        boolean b = mIWXAPI.sendReq(req);
                        LogUtils.i(TAG, "支付结果" + b);
                    } else {
                        LogUtils.i(TAG, "调起微信支付失败");
                    }
                } else {
                    ToastUtils.makeText(weiChatPayBeanStatusCode.getDetailMsg() + "");
                }
            }

            @Override
            protected void _onError(String message) {
                LogUtils.i(TAG, message);
                ToastUtils.makeText(message);
                LoadingDialogUtils.closeDialog(loadingDialog);
            }

        }, "", lifecycleSubject, false, true);
    }

    private void payByAlipay(StringBuffer buffer) {
        Observable observable =
                ApiUtils.getApi().payGoodsOrderByAlipay(BaseApplication.getToken(), BaseApplication.getUserId(), mOrderInfo.getOrderId(), buffer.toString())
                        .compose(RxHelper.getObservaleTransformer())
                        .doOnSubscribe(new Consumer<Disposable>() {
                            @Override
                            public void accept(Disposable disposable) throws Exception {
                                if (loadingDialog == null) {
                                    loadingDialog = LoadingDialogUtils.createLoadingDialog(CheckstandActivity.this, "");
                                }
                                LoadingDialogUtils.show(loadingDialog);
                            }
                        })
                        .subscribeOn(AndroidSchedulers.mainThread());

        HttpUtil.getInstance().toSubscribe(observable, new ProgressSubscriber<String>(CheckstandActivity.this) {
            @Override
            protected void _onNext(StatusCode<String> stringStatusCode) {
                LoadingDialogUtils.closeDialog(loadingDialog);
                final String apyStr = stringStatusCode.getData();
                if (stringStatusCode.isFlag() && !StringUtils.isEmpty(apyStr)) {
                    //成功
                    ThreadFactory.getNormalPool().execute(new Runnable() {
                        @Override
                        public void run() {
                            PayTask alipay = new PayTask(CheckstandActivity.this);
                            Map<String, String> result = alipay.payV2(apyStr, true);
                            LogUtils.i(TAG, result.toString());

                            Message msg = new Message();
                            msg.what = SDK_PAY_FLAG;
                            msg.obj = result;
                            mHandler.sendMessage(msg);
                        }
                    });
                } else {
                    ToastUtils.makeText(stringStatusCode.getDetailMsg());
                }
            }

            @Override
            protected void _onError(String message) {
                ToastUtils.makeText(message);
                LoadingDialogUtils.closeDialog(loadingDialog);
            }
        }, "", lifecycleSubject, false, true);
    }

    @SuppressLint("HandlerLeak")
    private Handler mHandler = new Handler() {
        @SuppressWarnings("unused")
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case SDK_PAY_FLAG: {
                    @SuppressWarnings("unchecked")
                    PayResult payResult = new PayResult((Map<String, String>) msg.obj);
                    /**
                     对于支付结果，请商户依赖服务端的异步通知结果。同步通知结果，仅作为支付结束的通知。
                     9000	订单支付成功
                     8000	正在处理中，支付结果未知（有可能已经支付成功），请查询商户订单列表中订单的支付状态
                     4000	订单支付失败
                     5000	重复请求
                     6001	用户中途取消
                     6002	网络连接出错
                     6004	支付结果未知（有可能已经支付成功），请查询商户订单列表中订单的支付状态
                     其它	其它支付错误
                     */
                    String resultInfo = payResult.getResult();// 同步返回需要验证的信息
                    String resultStatus = payResult.getResultStatus();
                    // 判断resultStatus 为9000则代表支付成功
                    if (TextUtils.equals(resultStatus, "9000")) {
                        // 该笔订单是否真实支付成功，需要依赖服务端的异步通知。
                        ToastUtils.makeText("支付成功");
                        startActivity(PaySuccessActivity.call2SuccessActivity(CheckstandActivity.this, SuccessFromType.PAY));
                        finish();
                    } else {
                        //失败
                        ToastUtils.makeText("支付失败");
                    }
                    break;
                }
                default:
                    break;
            }
        }

        ;
    };

    @OnTextChanged(R.id.tv_deduction_coupon_activity_checkstand)
    public void onTextChanged(Editable e) {
        mTvCouponActivityCheckstand.setText(String.format(getString(R.string.string_sub_pay), format.format(mCouponsSum)));

        BigDecimal paySum = new BigDecimal(mOrderInfo.getActualPrice())
                .subtract(new BigDecimal(mExpressSum))
                .subtract(new BigDecimal(mCouponsSum));
        mGoodsSumCurrent = paySum.doubleValue();

        refreshPayButton();
    }

    @OnClick({R.id.relative_wechant_activity_checkstand, R.id.relative_zhifubao_activity_checkstand,
            R.id.relative_coupons_activity_checkstand, R.id.btn_pay_activity_checkstand})
    public void onClickM(View view) {
        switch (view.getId()) {
            case R.id.relative_wechant_activity_checkstand:
                mTvWechantActivityCheckstand.setEnabled(true);
                mTvZhifubaoActivityCheckstand.setEnabled(false);
                mPayType = PayType.WEICHANT;
                refreshPayButton();
                break;
            case R.id.relative_zhifubao_activity_checkstand:
                mTvZhifubaoActivityCheckstand.setEnabled(true);
                mTvWechantActivityCheckstand.setEnabled(false);
                mPayType = PayType.ZHIFUBAO;
                refreshPayButton();
                break;
            case R.id.relative_coupons_activity_checkstand:
                if (hasCoupons) {
                    startActivityForResult(
                            SelectorCouponsActivity.call2SelectorCouponsActivity(this, mAllCoupons, mChooseCoupons),
                            REQUEST_ORDER_COUPONS);
                    break;
                }
            case R.id.btn_pay_activity_checkstand:
                StringBuffer buffer = new StringBuffer("");
                if (mChooseCoupons != null && mChooseCoupons.size() > 0) {
                    for (CouponsBean bean :
                            mChooseCoupons) {
                        buffer.append(bean.getId()).append("-");
                    }
                    buffer.deleteCharAt(buffer.length() - 1);
                }
                if (mPayType == PayType.WEICHANT) {
                    payByWechat(buffer);
                } else if (mPayType == PayType.ZHIFUBAO) {
                    payByAlipay(buffer);
                }
        }
    }
}
